package com.proxy.server.handler;


import com.proxy.common.codec.http.MyHttpRequestEncoder;
import com.proxy.common.entity.ClientNode;
import com.proxy.common.entity.LocalPort;
import com.proxy.common.entity.ProxyRealServer;
import com.proxy.common.protocol.CommonConstant;
import com.proxy.common.protocol.Message;
import com.proxy.server.service.ServerBeanManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 处理用户请求的handler
 * @author ztgreat
 */
public class HttpChannelHandler extends ChannelInboundHandlerAdapter {

    private static Logger logger = LoggerFactory.getLogger(HttpChannelHandler.class);


    /**
     * 用于http 消息编码处理
     * @// TODO: 2018/2/10 需要review
     */
    private MyHttpRequestEncoder httpRequestEncoder;

    public HttpChannelHandler(){
        super();
        httpRequestEncoder =new MyHttpRequestEncoder();
    }


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        //http 请求
        if (msg instanceof FullHttpRequest){
            FullHttpRequest request = (FullHttpRequest) msg;
            //处理http消息
            httpHandler(ctx,request);
            ReferenceCountUtil.release(msg);
        }else {
            logger.error("丢弃消息");
        }
    }


    /**
     * 处理http 请求
     * @param ctx
     * @param request
     * @throws Exception
     */
    public  void httpHandler(ChannelHandlerContext ctx,FullHttpRequest request) throws  Exception{


        Channel userChannel=ctx.channel();
        InetSocketAddress sa = (InetSocketAddress) userChannel.localAddress();

        LocalPort localPort = ServerBeanManager.getLocalPortBindService().get(sa.getPort());

        if (localPort == null) {

            // 该端口还没有代理客户端
            logger.error("端口{} 没有代理客户端",sa.getPort());
            userChannel.close();
            return;
        }
        ClientNode node = ServerBeanManager.getProxyService().get(localPort.getClientKey());
        if (node==null || node.getChannel()==null){
            logger.error("端口{} 没有代理客户端",sa.getPort());
            userChannel.close();
            return;
        }

        //封装消息
        Long sessionID= ServerBeanManager.getUserSessionService().getSessionID(userChannel);

        ProxyRealServer realServer=node.getServerPort2RealServer().get(sa.getPort());

        //设置host为请求服务器地址
        request.headers().set("host",realServer.getAddress());

        //设置 sessionID,记录会话
        request.headers().add(CommonConstant.SESSION_NAME,sessionID);


        List<Object>list=new ArrayList<>();
        httpRequestEncoder.encode(ctx,request,list);

        for (Object o:list){
            ByteBuf buf= (ByteBuf)o;
            byte[] data=new byte[buf.readableBytes()];
            buf.readBytes(data);
            buf.release();
            Message message=new Message();
            message.setClientChannel(node.getChannel());
            message.setData(data);
            message.setsPort(sa.getPort());
            message.setSessionID(sessionID);
            message.setType(CommonConstant.MessageType.TYPE_TRANSFER);
            message.setProxyType((byte) CommonConstant.ProxyType.HTTP);

            logger.debug("来自{}端口的请求转发至客户端({})",sa.getPort(),node.getClientKey());

            ServerBeanManager.getTransferService().toClient(message);
        }





    }
}
